﻿#region Disclaimer/Info
 
 /////////////////////////////////////////////////////////////////////////////////////////////////
 //
 //   File:		RoleRepository.cs
 //   Website:		http://dexterblogengine.com/
 //   Authors:		http://dexterblogengine.com/About.ashx
 //   Rev:		1
 //   Created:		23/02/2011
 //   Last edit:		23/02/2011
 //   License:		GNU Library General Public License (LGPL)
 //   File:            RoleRepository.cs
 //   For updated news and information please visit http://dexterblogengine.com/
 //   Dexter is hosted to Codeplex at http://dexterblogengine.codeplex.com
 //   For any question contact info@dexterblogengine.com
 //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 #endregion

using System;
using System.Collections.Generic;
using Dexter.Core.Data.Repository;
using Dexter.Domain.Model;
using Dexter.Logger.Contracts;
using Dexter.Repository.NHibernate.Queries;
using Dexter.Repository.NHibernate.SessionFactory;
using Topics.Radical.Validation;

namespace Dexter.Repository.NHibernate.Repositories
{

	/// <summary>
	/// The implementation of <see cref="IRoleRepository"/>.
	/// </summary>
	/// <example>The following is an example of initializing 
	///          an <c>RoleRepository</c> type:
	///   <code>
	///       // Create the type.
	///       RoleRepository ds = new RoleRepository;
	/// 
	///       if ( null == ds )
	///           return;
	/// 
	///       return ds.DoSomething( 5 );
	///   </code>
	/// </example>
	public class RoleRepository : RepositoryBase<Role>, IRoleRepository
	{

		/// <summary>
		/// Initializes a new instance of the <see cref="RoleRepository"/> class.
		/// </summary>
		/// <param name="sessionFactory">The session factory.</param>
		/// <param name="logger">The logger.</param>
		public RoleRepository(ISessionFactory sessionFactory, ILogger logger) : base(sessionFactory, logger) { }

		#region Implementation of IRoleRepository

		public bool RoleExists ( string roleName ) {
			Ensure.That ( roleName )
				.Named ( "roleName" )
				.WithPreview ( ( v, e ) => Logger.Warn ( v.GetFullErrorMessage ( ), e ) )
				.IsNotNullNorEmpty ( )
				.WithMessage ( "Invalid roleName" );

			return Session.GetNamedQuery ( KnownQueries.RoleRepository.GetUsersInRole )
			       	.SetParameter ( "name" , roleName )
			       	.UniqueResult <int> ( ) > 0;
		}

		/// <summary>
		/// Saves the specified role into the repository.
		/// </summary>
		/// <param name="item">The item.</param>
		/// <exception cref="ArgumentNullException"> If <paramref name="item"/> is <c>null</c>.</exception>
		public virtual void Save(Role item)
		{
			Ensure.That(item)
				.Named("item")
				.WithPreview((v, e) => Logger.Warn(v.GetFullErrorMessage(), e))
				.IsNotNull()
				.WithMessage("Invalid role");

			item.ValidateForSave();

			base.Add(item);
		}

		/// <summary>
		/// Updates the specified role into the repository.
		/// </summary>
		/// <param name="item">The item.</param>
		/// <exception cref="ArgumentNullException"> If <paramref name="item"/> is <c>null</c>.</exception>
		public virtual void Update(Role item)
		{
			Ensure.That(item)
				.Named("item")
				.WithPreview((v, e) => Logger.Warn(v.GetFullErrorMessage(), e))
				.IsNotNull()
				.WithMessage("Invalid role");

			item.ValidateForUpdate();

			Session.Update(item);
		}

		/// <summary>
		/// Deletes the specified role into the repository.
		/// </summary>
		/// <param name="item">The item.</param>
		/// <exception cref="ArgumentNullException"> If <paramref name="item"/> is <c>null</c>.</exception>
		public virtual void Delete(Role item)
		{
			Ensure.That(item)
				.Named("item")
				.WithPreview((v, e) => Logger.Warn(v.GetFullErrorMessage(), e))
				.IsNotNull()
				.WithMessage("Invalid role");

			item.ValidateForDelete();

			base.Remove(item);
		}

		/// <summary>
		/// Gets the users in role.
		/// </summary>
		/// <param name="roleName">Name of the role.</param>
		/// <returns></returns>
		public IEnumerable<User> GetUsersInRole(string roleName)
		{
			Ensure.That(roleName)
				.Named("roleName")
				.WithPreview((v, e) => Logger.Warn(v.GetFullErrorMessage(), e))
				.IsNotNullNorEmpty()
				.WithMessage("Invalid roleName");

			IEnumerable<User> users = Session.GetNamedQuery(KnownQueries.RoleRepository.GetUsersInRole)
				.SetParameter("name", roleName).List<User>();
			
			return users;	
		}

		#endregion
	}
}